import type { Property } from 'csstype';
import { maskStyle } from './mask.css';

export const DragMask = {
	show(
		evt: PointerEvent,
		cursor: Property.Cursor,
		onMove: (evt: PointerEvent, distance: { x: number; y: number }) => void,
		onClose?: (evt: PointerEvent) => void,
	) {
		const startX = evt.clientX;
		const startY = evt.clientY;
		evt.preventDefault();
		evt.stopPropagation();
		const pointerId = evt.pointerId;
		const mask = (<div class={[maskStyle, 'drag']} style={{ cursor: cursor }} />) as HTMLDivElement;
		document.body.append(mask);
		mask.setPointerCapture(pointerId);
		mask.addEventListener('pointermove', move);
		mask.addEventListener('pointercancel', (ev) => {
			close(ev);
		});
		mask.addEventListener('pointerup', (ev) => {
			close(ev);
		});
		function move(evt: PointerEvent) {
			if (evt.pointerId === pointerId) {
				evt.preventDefault();
				evt.stopPropagation();
				onMove(evt, { x: evt.clientX - startX, y: evt.clientY - startY });
			}
		}
		function close(ev: PointerEvent) {
			if (ev.pointerId === pointerId) {
				mask.releasePointerCapture(evt.pointerId);
				mask.remove();
				onClose?.(ev);
			}
		}
		return mask;
	},
};

let ref = 0;
let mask: HTMLDivElement | null = null;

export const Mask = {
	show(delay = 0) {
		if (ref === 0) {
			const div = (<div class={[maskStyle, 'mask']} />) as HTMLDivElement;
			document.body.append(div);
			mask = div;
			setTimeout(
				() => {
					div.classList.add('active');
				},
				delay > 16 ? delay : 16,
			);
		}
		ref++;
	},
	close() {
		if (ref > 0) {
			ref--;
			if (ref === 0 && mask) {
				const m = mask;
				mask.classList.remove('active');
				setTimeout(() => {
					m.remove();
					if (ref <= 0) {
						mask = null;
					}
				}, 200);
			}
		}
	},
};
